﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using DevExpress.Utils;
using DevExpress.XtraGrid.Columns;
using E4RPDevExpress10;
using E4RPTools;
using HouseRental.DataSets;

namespace HouseRental.Controls
{
    public partial class Estimate : UserControl
    {
        private Controller _controller;
        private bool _showingEstimate;
        private bool _initNewRow;

        #region Properties

        public Controller Controller
        {
            set
            {
                _controller = value;
                _controller.EstimateShow += delegate { UpdateControl(); };
                _controller.EstimateStateChange += delegate { stateTextEdit.Text = _controller.Estimate.Orcamento[0].Estado; };
                _controller.EstimateCloseEditors += delegate { CloseEditors(); };
            }
        }

        #endregion

        public Estimate()
        {
            InitializeComponent();
            FormatGridColumns();
            gridView.InitNewRow += GridViewInitNewRow;
            gridView.CellValueChanged += GridViewCellValueChanged;
            houseRentalLookUpEdit.EditValueChanging += HouseRentalLookUpEditEditValueChanging;
            productRepositoryItemLookUpEdit.EditValueChanging += ProductRepositoryItemLookUpEditEditValueChanging;
            gridView.ShowingEditor += GridViewShowingEditor;
        }
        
        #region Private Methods

        private void SetupHouseRentalData()
        {
            condominioDataSet.Clear();
            condominioDataSet.Merge(_controller.HouseRentals());
            houseRentalLookUpEdit.Properties.DataSource = condominioDataSet.Condomínio;
            houseRentalLookUpEdit.Properties.DisplayMember = condominioDataSet.Condomínio.NomeColumn.ToString();
            houseRentalLookUpEdit.Properties.ValueMember = condominioDataSet.Condomínio.IdColumn.ToString();
            houseRentalLookUpEdit.Properties.Columns.Clear();
            houseRentalLookUpEdit.Properties.Columns.AddRange(new[] {
                new DevExpress.XtraEditors.Controls.LookUpColumnInfo("Nome", "Nome", 70, FormatType.None, "", true, HorzAlignment.Near)});
            houseRentalLookUpEdit.ClosePopup();
        }

        private void SetupProductData()
        {
            productRepositoryItemLookUpEdit.PopupWidth = 450;
            produtoDataSet.Clear();
            produtoDataSet.Merge(_controller.Products(_controller.Estimate.Orcamento[0].IdCondominio));
            productRepositoryItemLookUpEdit.DataSource = produtoDataSet.Produto;
            productRepositoryItemLookUpEdit.DisplayMember = produtoDataSet.Produto.ReferenciaColumn.ToString();
            productRepositoryItemLookUpEdit.ValueMember = produtoDataSet.Produto.ReferenciaColumn.ToString();
            productRepositoryItemLookUpEdit.Columns.Clear();
            productRepositoryItemLookUpEdit.Columns.AddRange(new[] {
                new DevExpress.XtraEditors.Controls.LookUpColumnInfo("Familia", "Familia", 70, FormatType.None, "", true, HorzAlignment.Near),
                new DevExpress.XtraEditors.Controls.LookUpColumnInfo("Referencia", "Referencia", 100, FormatType.None, "", true, HorzAlignment.Near),
                new DevExpress.XtraEditors.Controls.LookUpColumnInfo("Descricao", "Descricao", 280, FormatType.None, "", true, HorzAlignment.Near)});
        }
        
        private void SetupGridData()
        {
            gridControl.DataSource = null;
            gridControl.DataMember = "";
            gridControl.DataSource = _controller.Estimate;
            gridControl.DataMember = _controller.Estimate.ItemOrcamento.TableName;
        }

        private void SetDataToControls()
        {
            nameTextEdit.Text = _controller.Estimate.Orcamento[0].Nome;
            yearSpinEdit.EditValue = _controller.Estimate.Orcamento[0].Ano;
            houseRentalLookUpEdit.EditValue = _controller.Estimate.Orcamento[0].IdCondominio;
            stateTextEdit.Text = _controller.Estimate.Orcamento[0].Estado;
        }

        private void FormatGridColumns()
        {
            DevExpressHelper.SetColumnAsCurrency(colTotal);
            DevExpressHelper.SetColumnAsCurrency(colJaneiro);
            DevExpressHelper.SetColumnAsCurrency(colFevereiro);
            DevExpressHelper.SetColumnAsCurrency(colMarco);
            DevExpressHelper.SetColumnAsCurrency(colAbril);
            DevExpressHelper.SetColumnAsCurrency(colMaio);
            DevExpressHelper.SetColumnAsCurrency(colJunho);
            DevExpressHelper.SetColumnAsCurrency(colJulho);
            DevExpressHelper.SetColumnAsCurrency(colAgosto);
            DevExpressHelper.SetColumnAsCurrency(colSetembro);
            DevExpressHelper.SetColumnAsCurrency(colOutubro);
            DevExpressHelper.SetColumnAsCurrency(colNovembro);
            DevExpressHelper.SetColumnAsCurrency(colDezembro);
        }

        private void UpdateControl()
        {
            _showingEstimate = true;
            SetupHouseRentalData();
            SetupProductData();
            SetDataToControls();
            SetupGridData();
            FormatGridColumns();            
            houseRentalLookUpEdit.Enabled = _controller.Estimate.Orcamento[0].Id < 0;
            yearSpinEdit.Enabled = _controller.Estimate.Orcamento[0].Id < 0;
            houseRentalLookUpEdit.ClosePopup();
            houseRentalLookUpEdit.Enabled = false;
            _showingEstimate = false;            
        }

        private ProdutoDataSet.ProdutoRow GetProduct(string reference)
        {
            foreach (ProdutoDataSet.ProdutoRow product in produtoDataSet.Produto)
                if (product.Referencia == reference)
                    return product;
            return null;
        }

        private Control GetControl(string reference)
        {
            switch (reference)
            {
                case "IdCondominio":
                    return houseRentalLookUpEdit;
                case "Ano":
                    return yearSpinEdit;
                default:
                    return null;
            }
        }

        private bool IsMonthColumn(GridColumn column)
        {
            if (column == colJaneiro) return true;
            if (column == colFevereiro) return true;
            if (column == colMarco) return true;
            if (column == colAbril) return true;
            if (column == colMaio) return true;
            if (column == colJunho) return true;
            if (column == colJulho) return true;
            if (column == colAgosto) return true;
            if (column == colSetembro) return true;
            if (column == colOutubro) return true;
            if (column == colNovembro) return true;
            return column == colDezembro;
        }

        #endregion

        public void CloseEditors()
        {
            if(_controller.Estimate.Orcamento[0].IdCondominio != (string)houseRentalLookUpEdit.EditValue)
                _controller.Estimate.Orcamento[0].IdCondominio = (string)houseRentalLookUpEdit.EditValue;
            if(_controller.Estimate.Orcamento[0].Ano != Convert.ToInt32(yearSpinEdit.EditValue))
                _controller.Estimate.Orcamento[0].Ano = Convert.ToInt32(yearSpinEdit.EditValue);
            gridView.CloseEditor();
            gridView.UpdateCurrentRow();
        }

        public void ClearControlErrors()
        {
            dxErrorProvider.SetError(houseRentalLookUpEdit, "");
            dxErrorProvider.SetError(yearSpinEdit, "");
            dxErrorProvider.SetError(gridControl, "");
        }

        public decimal GetValue()
        {
            if(gridView.GetDataRow(gridView.FocusedRowHandle) == null)
                return 0;
            gridView.CloseEditor();
            gridView.UpdateCurrentRow();
            return Convert.ToDecimal(gridView.FocusedValue);            
        }

        public List<OrcamentoDataSet.ItemOrcamentoRow> SelectedEstimateItems()
        {
            var estimates = new List<OrcamentoDataSet.ItemOrcamentoRow>();
            if (gridView.SelectedRowsCount == 0 && gridView.GetDataRow(gridView.FocusedRowHandle) != null)
            {
                gridView.CloseEditor();
                gridView.UpdateCurrentRow();
                estimates.Add((OrcamentoDataSet.ItemOrcamentoRow) gridView.GetDataRow(gridView.FocusedRowHandle));
                return estimates;
            }
            if (gridView.SelectedRowsCount == 0)
                return estimates;            
            foreach (int handle in gridView.GetSelectedRows())
                estimates.Add((OrcamentoDataSet.ItemOrcamentoRow)gridView.GetDataRow(handle));
            return estimates;            
        }
        
        public void SetControlErrors(Result result)
        {
            foreach (Error error in result.Errors)
                dxErrorProvider.SetError(GetControl(error.Reference), error.Message);
        }

        public void SetFocusedColumnAsTotal()
        {
            gridView.FocusedColumn = colTotal;
            gridView.FocusedColumn = colJaneiro;
            gridView.FocusedColumn = colTotal;
        }


        void GridViewInitNewRow(object sender, DevExpress.XtraGrid.Views.Grid.InitNewRowEventArgs e)
        {
            _initNewRow = true;
            gridView.SetRowCellValue(e.RowHandle, colIdItem, _controller.GetNextEstimateItemId());
            gridView.SetRowCellValue(e.RowHandle, colId, _controller.Estimate.Orcamento[0].Id);
            gridView.SetRowCellValue(e.RowHandle, colTotal, 0);
            gridView.SetRowCellValue(e.RowHandle, colJaneiro, 0);
            gridView.SetRowCellValue(e.RowHandle, colFevereiro, 0);
            gridView.SetRowCellValue(e.RowHandle, colMarco, 0);
            gridView.SetRowCellValue(e.RowHandle, colAbril, 0);
            gridView.SetRowCellValue(e.RowHandle, colMaio, 0);
            gridView.SetRowCellValue(e.RowHandle, colJunho, 0);
            gridView.SetRowCellValue(e.RowHandle, colJulho, 0);
            gridView.SetRowCellValue(e.RowHandle, colAgosto, 0);
            gridView.SetRowCellValue(e.RowHandle, colSetembro, 0);
            gridView.SetRowCellValue(e.RowHandle, colOutubro, 0);
            gridView.SetRowCellValue(e.RowHandle, colNovembro, 0);
            gridView.SetRowCellValue(e.RowHandle, colDezembro, 0);
            _initNewRow = false;            
        }

        void GridViewCellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
        {
            if (_showingEstimate || _initNewRow) return;
            if (!IsMonthColumn(e.Column)) return;
            var estimateItem = (OrcamentoDataSet.ItemOrcamentoRow)gridView.GetDataRow(e.RowHandle);
            _controller.UpdateEstimateItemTotal(estimateItem);
        }
        
        void HouseRentalLookUpEditEditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
        {
            if (_showingEstimate) return;            
            _controller.UpdateHouseRental(e.NewValue.ToString());            
            SetupProductData();
        }

        void ProductRepositoryItemLookUpEditEditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
        {
            if (_showingEstimate) return;
            int rowHandle = gridView.FocusedRowHandle;
            ProdutoDataSet.ProdutoRow product = GetProduct(e.NewValue.ToString());
            gridView.SetRowCellValue(rowHandle, colDescricao, product.Descricao);            
        }

        void GridViewShowingEditor(object sender, System.ComponentModel.CancelEventArgs e)
        {
            e.Cancel = _controller.Estimate.Orcamento[0].Estado == EstimateState.Bloqueado.ToString();
        }


    }
}
